#include "socket_glue_code.h"
#include <string>
#include <sys/types.h>
#include <cstring>
#include <iostream>
#include <stdio.h>

#define ERROR 0
#define INFO 1
#define TRACE 2

using namespace std;

const int PORT = 8085;

#ifndef WIN32
//not available on LINUX I guess?
#define __stdcall
typedef void* LPVOID;
#endif

void log (int level, string errorReason, string errorCause);
DWORD __stdcall handle_connection(LPVOID connection_data);
void create_thread(DWORD __stdcall (*thread_method) (LPVOID),LPVOID socket_descriptor);

int main(int argc, char **argv)
{
    startWin32();
    SOCKET listen_descriptor, socket_descriptor;


    static struct sockaddr_in serv_addr; /* static = initialised to zeros */
    static struct sockaddr_in cli_addr;
    socklen_t length = sizeof(cli_addr);


    if((listen_descriptor = socket(AF_INET, SOCK_STREAM,0)) <0)
        log(ERROR, "system call","socket");

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(PORT);

    if(bind(listen_descriptor, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) <0)
        log(ERROR,"system call","bind");

    if( listen(listen_descriptor,64) <0)
        log(ERROR,"system call","listen");

    while (true){
        socket_descriptor = accept(listen_descriptor, (struct sockaddr *) &cli_addr, &length);
            if(socket_descriptor < 0 || socket_descriptor == SOCKET_ERROR){
                log(ERROR,"system call","accept");
#ifdef WIN32
                printWindowsSocketError();
#endif
            }
            create_thread(handle_connection, (LPVOID) &socket_descriptor);
    }
    stopWin32();
}

DWORD __stdcall handle_connection(LPVOID connection_data){
    SOCKET *socket_descriptor_ptr = (SOCKET *) (connection_data);
    SOCKET socket_descriptor = *socket_descriptor_ptr;
    //We need to really do something here...
    log (INFO, "socket", "connection accepted");
      cout << read_socket(socket_descriptor);
      static char buffer[8096+1];
       char * fstr;
      sprintf(buffer,"HTTP/1.0 200 OK\r\n\r\n");

      write(socket_descriptor ,buffer,strlen(buffer));
      close(socket_descriptor);
    return 0;
}



void log (int level, string errorReason, string errorCause){
    cout << errorReason << " " << errorCause <<  endl;
}

void create_thread(DWORD __stdcall (*thread_method) (LPVOID),LPVOID socket_descriptor)
{
            // we need to find the linux equivalent to this and make it work on both systems
#ifdef WIN32
			CreateThread( NULL,
                0,
                thread_method,
                (LPVOID) socket_descriptor,
                0,
                0
            );
#endif
            /*handleConnection(socket_descriptor, cli_addr, length);*/
}
